﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Scheduling.Models.Helpers;
using Scheduling.Models;
using Scheduling.Models.Interfaces;

namespace Scheduling.Controllers
{
    public class BookingController : BaseController
    {
        [Restrict(Roles = "Bookers")]
        public ActionResult List()
        {
            var bookingLoader = IoC.Resolve<IBookingLoader>();

            var bookings = bookingLoader.GetBookingsByUserID(UserHelper.GetAuthenticatedUserID());

            bookings = bookings.Where(b => b.StartDate > DateTime.Now.AddYears(-1))
               .OrderBy(b => b.StartDate)
               .ThenBy(b => b.CourseInstance.ID).ToList();

            return View(bookings);
        }

        [Restrict(Roles = "Bookers")]
        public ActionResult ListAll()
        {
            var bookingLoader = IoC.Resolve<IBookingLoader>();

            var bookings = bookingLoader.GetBookings();

            bookings = bookings.Where(b => b.StartDate > DateTime.Now.AddYears(-1))
                .OrderBy(b => b.StartDate)
                .ThenBy(b => b.CourseInstance.ID).ToList();

            return View(bookings);
        }

        public ActionResult Show(int id)
        {
            var bookingLoader = IoC.Resolve<IBookingLoader>();

            var booking = bookingLoader.GetBooking(id);

            if (booking == null) 
                FileNotFound();

            return View(booking);
        }

        public ActionResult Edit()
        {
            return View();
        }

        [HttpGet]
        [Restrict(Roles="Bookers")]
        public ActionResult Delete(int id)
        {
            var bookingLoader = IoC.Resolve<IBookingLoader>();

            var booking = bookingLoader.GetBooking(id);

            if (booking == null)
                FileNotFound();

            return View(booking);
        }

        [HttpPost]
        [Restrict(Roles="Bookers")]
        public ActionResult Delete(int id, string inConfirm)
        {
            if (inConfirm.StartsWith("Yes"))
            {
                var bookingLoader = IoC.Resolve<IBookingLoader>();

                bookingLoader.DeleteBooking(id);
            }
            return RedirectToAction("List");
        }

        [HttpGet]
        [Restrict(Roles="Bookers")]
        public ActionResult Add()
        {
            ViewData["UserID"] = UserHelper.GetAuthenticatedUserID();

            return View();
        }

        [HttpPost]
        [Restrict(Roles="Bookers")]
        public ActionResult Add(FormCollection Form)
        {
            ViewData["collision"] = "false";
            DateTime startDate;
            DateTime endDate;
            
            var userLoader = IoC.Resolve<IUserLoader>();
            var roomLoader = IoC.Resolve<IRoomLoader>();
            var courseInstanceLoader = IoC.Resolve<ICourseInstanceLoader>();
            var bookingLoader = IoC.Resolve<IBookingLoader>();

            //Load Viewdata in case of error
            ViewData["UserID"] = UserHelper.GetAuthenticatedUserID();
            foreach (string key in Form.Keys)
                ViewData[key] = Form.Get(key);

            //Try to parse Dates & CourseID
            if (!DateTime.TryParse(Form.Get("inStartDate") + " " + Form.Get("inStartTime"), out startDate))
                return View((object)"Invalid Start Date");
            if (!DateTime.TryParse(Form.Get("inEndDate") + " " + Form.Get("inEndTime"), out endDate))
                return View((object)"Invalid End Date");
            if (startDate >= endDate)
                return View((object)"Your End Date is before or equal to your Start Date");
            
            //Check that all objects exist
            if (!roomLoader.RoomExists(Form.Get("inRoom")))
                return View((object)"Specified Room does not exist");

            //Load values

            User user = UserHelper.GetAuthenticatedUser();
            Room room = roomLoader.GetRoom(Form.Get("inRoom"));
            CourseInstance courseInstance;
            string[] splitstring = Form.Get("inCourse").Split('(');
            if (splitstring.Count() == 2)
            {
                splitstring = splitstring[1].Split(' ');
                if (splitstring.Count() == 3)
                {
                    int id;
                    if (Int32.TryParse(splitstring[0], out id))
                        courseInstance = courseInstanceLoader.GetCourseInstance(id);
                    else
                        return View((object)"Incorrect format of course");
                }
                else
                    return View((object)"Incorrect format of course");
            }
            else
            {
                return View((object)"Incorrect format of course");
            }
                      

            if(courseInstance==null)
                return View((object)"No Course With that code");

                Booking booking = new Booking()
            {
                ID = 0,
                User = user,
                Room = room,
                CourseInstance = courseInstance,
                StartDate = startDate,
                EndDate = endDate
            };

            //Check for collisions
            var collisions = bookingLoader.GetCollisions(booking);
            if (collisions.Count() > 0)
            {
                ViewData["collision"] = "true";
                if (Form.Get("bookanyway") == "true")
                {
                    bookingLoader.InsertBooking(booking);
                    return View();
                }
                else
                    return View(collisions);
            }

            //Insert booking
            bookingLoader.InsertBooking(booking);

            return RedirectToAction("List");
        }
    }
}
